/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.eng.scc.core.editors;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

/**
 *
 * @author Rafael
 */
public class DefaultEditor<A> extends JDialog
{   
    private transient String title = "title";
    private transient Dimension dimension  = new Dimension( 400, 400 );//DEFAULT DIMENSION
    
    private AbstractPanelEditor<A> editor = null;

    public boolean acepted = false;

    public boolean isAcepted()
    {
        return acepted;
    }
    
    public static final int OK_CANCEL_BUTTON = 0;
    public static final int CLOSE_BUTTON = 1;    
    
    private int option = OK_CANCEL_BUTTON;
    
    public static <A> boolean createEditor( Component parent, String title, String info, Dimension dimension, int option, AbstractPanelEditor<A> editor )
    {
        if ( editor == null )
        {
            throw new IllegalArgumentException( "editor cannot be null!" );
        }
        
        DefaultEditor<A> defaultEditor = new DefaultEditor<A>( parent, title, dimension, option );
        
        defaultEditor.infoLabel.setText( info );
        defaultEditor.setModal( true );
        defaultEditor.setEditor( editor );
        defaultEditor.setVisible( true );
        
        return defaultEditor.isAcepted();
    }
    
    public static <A> boolean createEditor( Component parent, String title, String info, Dimension dimension, AbstractPanelEditor<A> editor )
    {
        return createEditor( parent, title, info ,dimension, OK_CANCEL_BUTTON, editor );
    }

    private DefaultEditor(){/*DO NOT NEED INSTANCE FOR THAT...*/}
    
    public void setEditor( AbstractPanelEditor<A> editor )
    {
        this.editor = editor;
        
        this.contentPane.add( this.editor, 
                              BorderLayout.CENTER );
        
        this.repaint();
        setInitialFocus();
    }
    
    private static Window getWindowForComponent( Component parentComponent )
    {
        if ( parentComponent == null )
        {
            return null;
        }
        
        if ( parentComponent instanceof Frame || parentComponent instanceof Dialog )
        {
            return ( Window ) parentComponent;
        }
        
        return getWindowForComponent( parentComponent.getParent() );
    }
    
    private DefaultEditor( Component owner, String title, Dimension dimension, int option )
    {
        super( getWindowForComponent( owner ) );
        
        this.title = title;
        this.option = option;
        
        if ( dimension != null )
        {
            this.dimension = dimension;
        }
        
        initComponets();
        initButtons();
        
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        Dimension editorSize = getSize();

        setLocation( ( screenSize.width - editorSize.width ) / 2,
                     ( screenSize.height - editorSize.height ) / 2 );
    }

    @Override
    public String getTitle()
    {
        return title;
    }
    
    private void initButtons()
    {
        switch ( option )
        {
            case OK_CANCEL_BUTTON:
                
                panelButtons.add( btOk,
                                  new GridBagConstraints( 0, 0, 1, 1, 0.0, 0.0,
                                                          GridBagConstraints.WEST,
                                                          GridBagConstraints.NONE,
                                                          new Insets( 10, 5, 10, 5 ), 0, 0 ) );
                panelButtons.add( btClose,
                                  new GridBagConstraints( 1, 0, 1, 1, 0.0, 0.0,
                                                          GridBagConstraints.EAST,
                                                          GridBagConstraints.NONE,
                                                          new Insets( 10, 5, 10, 0 ), 0, 0 ) );
                
                this.getRootPane().setDefaultButton( btOk );
                
                break;

            case CLOSE_BUTTON:
                
                panelButtons.add( btClose,
                                  new GridBagConstraints( 0, 0, 1, 1, 0.0, 0.0,
                                                          GridBagConstraints.EAST,
                                                          GridBagConstraints.NONE,
                                                          new Insets( 10, 5, 10, 0 ), 0, 0 ) );
                
                break;
            default:
                throw new AssertionError();
        }
        
    }
    
    private void initComponets()
    {
        setLayout( new GridBagLayout() );
        designPane.setLayout( new GridBagLayout() );
        titlePane.setLayout( new GridBagLayout() );
        panelButtons.setLayout( new GridBagLayout() );
        contentPane.setOpaque( false );
        
        contentPane.setLayout( new BorderLayout() );
        
//        setAlwaysOnTop( true );
        setDefaultCloseOperation( JDialog.DISPOSE_ON_CLOSE );
        
        setSize( dimension );
        setTitle( title );
        
        infoLabel.setFont( Font.getFont( Font.SANS_SERIF ) );
        infoLabel.setForeground( Color.BLACK );
        
        btOk.setText( "OK" );
        btClose.setText( "Cancelar" );
        
        panelButtons.setBorder( BorderFactory.createMatteBorder( 0, 0, 0, 0, Color.gray ) );
        
        contentPane.setBorder( BorderFactory.createMatteBorder( 2, 2, 2, 2, Color.gray ) );
        
        designPane.add( infoLabel, 
                        new GridBagConstraints( 0, 0, 1, 1, 1.0, 0.0, 
                                                GridBagConstraints.WEST, 
                                                GridBagConstraints.NONE, 
                                                new Insets( 10,40,10,0 ) , 0, 0) );
        designPane.add( contentPane, 
                        new GridBagConstraints( 0, 1, 1, 1, 1.0, 1.0, 
                                                GridBagConstraints.CENTER, 
                                                GridBagConstraints.BOTH, 
                                                new Insets( 0,15,0,15 ) , 0, 0) );
        panelButtons.setOpaque(false);
        designPane.add( panelButtons, 
                        new GridBagConstraints( 0, 2, 1, 1, 1.0, 0.0, 
                                                GridBagConstraints.EAST, 
                                                GridBagConstraints.NONE, 
                                                new Insets( 0,25,0,25 ) , 0, 0) );
        
        add( designPane, 
            new GridBagConstraints( 0, 0, 1, 1, 1.0, 1.0, 
                                    GridBagConstraints.CENTER, 
                                    GridBagConstraints.BOTH, 
                                    new Insets( 0, 0, 0, 0) , 0, 0) );
        
        btOk.addActionListener( new ActionListener() 
        {
            @Override
            public void actionPerformed( ActionEvent e )
            {
                ok();
            }
        });
            
        btClose.addActionListener( new ActionListener() 
        {
            @Override
            public void actionPerformed( ActionEvent e )
            {
                close();
            }
        });
    }
    
    private void ok()
    {
        if ( validateEditor() )
        {
            editor.getSource();
            acepted = true;
            setVisible( false );
            dispose();
        }
    }
    
    private void close()
    {
        acepted = false;
        setVisible( false );
        dispose();
    }
    
    private JButton btOk = new JButton();
    private JButton btClose = new JButton();
    private JPanel panelButtons = new JPanel();

    private JPanel contentPane = new JPanel();
    private JPanel titlePane = new JPanel();
    
    private JLabel infoLabel = new JLabel("DefaultEditor");
    
    private JPanel designPane = new JPanel()
    {
        @Override
        public void paintComponent( Graphics g )
        {
            super.paintComponent( g );

            Graphics2D g2d = ( Graphics2D ) g.create();

            g2d.setPaint( new GradientPaint( 0, 0, new Color( 190, 250, 223), 500,
                                             100, Color.WHITE, true ) );

            Rectangle rec = new Rectangle( 0, 0, getWidth(), getHeight() );
            g2d.fill( rec );

            g2d.setPaint( new GradientPaint( 0, 0, Color.WHITE, 130,
                                             110, new Color( 51, 102, 255 ), false ) );

//            Ellipse2D.Double ellip = new Ellipse2D.Double( -150, -100, getWidth() / 2, getHeight() * 2 );
//            g2d.fill( ellip );
        }
    };

    private void setInitialFocus()
    {
        JComponent component = editor.focus();
        
        if ( component == null )
        {
            for ( Component comp : contentPane.getComponents() )
            {
                if ( comp instanceof JTextField )
                {
                    component = (JComponent) comp;
                    break;
                }
            }
        }
        
        if ( component != null )
        {
            component.requestFocus();
        }
    }

    private boolean validateEditor()
    {
        com.eng.scc.core.util.Error error = new com.eng.scc.core.util.Error();
        
        editor.validateEditor( error );
        
        if ( ! error.isEmpty() )
        {
            StringBuilder sb = new StringBuilder( "Os seguinte campos são obrigatórios:\n" );
            
            for ( String s : error )
            {
                sb.append( "\t" );
                sb.append( "- " );
                sb.append( s );
                sb.append( "\n" );
            }
            
            JOptionPane.showMessageDialog( this, sb.toString(), "Erro de validação", JOptionPane.ERROR_MESSAGE );
            return false;
        }
        
        return true;
    }
}
